/**  
 * 
 * @Title:  NettyDecode.java   
 * @Package com.org.framework.net.code   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: 123774135@qq.com     
 * @date:   2018年7月5日 下午3:24:28   
 * @version V1.0 
 * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 
 * 
 */  
package com.bicon.base.data.common.net.code;

import java.util.List;

import com.bicon.base.data.common.net.serialize.SerializeFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**   
 * @ClassName:  NettyDecode   
 * @Description:TODO注意有可能存在粘包的问题   
 * @author: 123774135@qq.com 
 * @date:   2018年7月5日 下午3:24:28   
 *     
 * @Copyright: 2018 
 * 
 */
public class NettyDecode extends ByteToMessageDecoder{

	private SerializeFactory serializeFactory;
	
	private static int MESSAGE_LENGTH = 4;//消息长度
	
	public NettyDecode(SerializeFactory serializeFactory) {
		this.serializeFactory = serializeFactory;
	}
	
	@Override
	protected void decode(ChannelHandlerContext arg0, ByteBuf arg1, List<Object> arg2) throws Exception {
		if(arg1.readableBytes() < MESSAGE_LENGTH) {
			//这个HEAD_LENGTH是我们用于表示头长度的字节数。  由于上面我们传的是一个int类型的值，所以这里HEAD_LENGTH的值为4.
			return ;
		}
		arg1.markReaderIndex();//记录下当前的位置
		int dataLength = arg1.readInt();// 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4
		if (dataLength < 0) { // 我们读到的消息体长度为0，这是不应该出现的情况，这里出现这情况，关闭连接。
			arg0.close();
	    }
		if(arg1.readableBytes() < dataLength) {
			//读到的消息体长度如果小于我们传送过来的消息长度，则resetReaderIndex. 这个配合markReaderIndex使用的。把readIndex重置到mark的地方
			arg1.resetReaderIndex();
			return ;
		}
		//如果读出来的消息长度大于规定的消息长度如何处理???????
		byte[] body = new byte[dataLength];  
		arg1.readBytes(body);
		Object o = serializeFactory.deserialize(body);
		arg2.add(o);
	}

}
